home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / shells / rc-1.000 / rc-1 / rc-1.5-linux / wait.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-07  |  2.1 KB  |  126 lines

  1. #include <errno.h>
  2. #include <setjmp.h>
  3. #include "rc.h"
  4. #include "jbwrap.h"
  5.  
  6. bool forked = FALSE;
  7.  
  8. static int rc_wait(int *);
  9.  
  10. typedef struct Pid Pid;
  11.  
  12. static struct Pid {
  13.     int pid, stat;
  14.     bool alive;
  15.     Pid *n;
  16. } *plist = NULL;
  17.  
  18. extern int rc_fork() {
  19.     Pid *new;
  20.     int pid = fork();
  21.     switch (pid) {
  22.     case -1:
  23.         uerror("fork");
  24.         rc_error(NULL);
  25.         /* NOTREACHED */
  26.     case 0:
  27.         forked = TRUE;
  28.         sigchk();
  29.         return 0;
  30.     default:
  31.         new = enew(Pid);
  32.         new->pid = pid;
  33.         new->alive = TRUE;
  34.         new->n = plist;
  35.         plist = new;
  36.         return pid;
  37.     }
  38. }
  39.  
  40. extern int rc_wait4(int pid, int *stat, bool nointr) {
  41.     Pid *r, *prev;
  42.     int ret;
  43.     /* first look for a child which may already have exited */
  44. again:    for (r = plist, prev = NULL; r != NULL; prev = r, r = r->n)
  45.         if (r->pid == pid)
  46.             break;
  47.     if (r == NULL) {
  48.         errno = ECHILD; /* no children */
  49.         uerror("wait");
  50.         *stat = 0x100; /* exit(1) */
  51.         return -1;
  52.     }
  53.     if (r->alive) {
  54.         while (pid != (ret = rc_wait(stat))) {
  55.             Pid *q;
  56.             if (ret < 0) {
  57.                 if (nointr)
  58.                     goto again;
  59.                 return ret;
  60.             }
  61.             for (q = plist; q != NULL; q = q->n)
  62.                 if (q->pid == ret) {
  63.                     q->alive = FALSE;
  64.                     q->stat = *stat;
  65.                     break;
  66.                 }
  67.         }
  68.     } else
  69.         *stat = r->stat;
  70.     if (prev == NULL)
  71.         plist = r->n; /* remove element from head of list */
  72.     else
  73.         prev->n = r->n;
  74.     efree(r);
  75.     return pid;
  76. }
  77.  
  78. extern List *sgetapids() {
  79.     List *r;
  80.     Pid *p;
  81.     for (r = NULL, p = plist; p != NULL; p = p->n) {
  82.         List *q;
  83.         if (!p->alive)
  84.             continue;
  85.         q = nnew(List);
  86.         q->w = nprint("%d", p->pid);
  87.         q->m = NULL;
  88.         q->n = r;
  89.         r = q;
  90.     }
  91.     return r;
  92. }
  93.  
  94. extern void waitforall() {
  95.     int stat;
  96.     while (plist != NULL) {
  97.         int pid = rc_wait4(plist->pid, &stat, FALSE);
  98.         if (pid > 0)
  99.             setstatus(pid, stat);
  100.         else
  101.             set(FALSE);
  102.         sigchk();
  103.     }
  104. }
  105.  
  106. /*
  107.    rc_wait: a wait() wrapper that interfaces wait() w/rc signals.
  108.    Note that the signal queue is not checked in this fn; someone
  109.    may want to resume the wait() without delivering any signals.
  110. */
  111.  
  112. static int rc_wait(int *stat) {
  113.     int r;
  114.     interrupt_happened = FALSE;
  115.     if (!setjmp(slowbuf.j)) {
  116.         slow = TRUE;
  117.         if (!interrupt_happened)
  118.             r = wait(stat);
  119.         else
  120.             r = -1;
  121.     } else
  122.         r = -1;
  123.     slow = FALSE;
  124.     return r;
  125. }
  126.